package java8.future;

import org.junit.Test;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @program JavaBase
 * @description:
 * @author: zhanglu
 * @create: 2020-02-28 11:04:00
 */
public class Call {

    @Test
    public void test01(){
        Future<String> future = invoke(() -> {
            Thread.sleep(10000);
            return "ok";
        });
        System.out.println(future.get());

        while (!future.isDone()){

        }
        System.out.println(future.get());

    }

    private static <T> Future<T> invoke(Callable<T> callable){
        AtomicReference<T> result = new AtomicReference<>();
        AtomicBoolean finished = new AtomicBoolean(false);
        new Thread(() -> {
            try {
                T call = callable.call();
                result.set(call);
                finished.set(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();

        Future<T> future = new Call.Future<T>() {
            @Override
            public T get() {
                return result.get();
            }

            @Override
            public boolean isDone() {
                return finished.get();
            }
        };
        return future;
    }

    private interface Future<T>{
        T get();
        boolean isDone();
    }


    @Test
    public void test02(){
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        java.util.concurrent.Future<Integer> future = executorService.submit(() -> {
            int i = 1 / 0;
            return 1;
        });

        try {
            future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }

}
